home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Very Best of Atari Inside
/
The Very Best of Atari Inside 1.iso
/
mint
/
mgr_2
/
contrib
/
atari
/
vt52.c
< prev
Wrap
C/C++ Source or Header
|
1990-09-29
|
6KB
|
317 lines
#include "term.h"
#include <osbind.h>
#include <mintbind.h>
#include <keycodes.h>
#include <process.h>
#include <signal.h>
#include <sgtty.h>
/* key that gets us out of VT52 -- ^G, for now */
#define QUITKEY '\007'
extern void normal_putch(), escy_putch();
int kidpid; /* child's process id */
int kidfd; /* child's file descriptor */
int savex, savey; /* saved x, y coordinates */
void (*state)();
/*
* clrfrom(x1, y1, x2, y2): clear screen from position (x1,y1) to
* position (x2, y2) inclusive. It is assumed that y2 >= y1.
*/
void
clrfrom(x1, y1, x2, y2)
int x1,y1,x2,y2;
{
}
void
ignore()
{
state = normal_putch;
}
/*
* putesc(v, c): handle the control sequence ESC c
*/
#define gotoxy(x, y) m_move(x, y)
void
putesc(c)
int c;
{
int cx, cy;
switch (c) {
case 'A': /* cursor up */
m_up(10); /* BUG -- this scrolls; it shouldn't */
break;
case 'B': /* cursor down */
m_down(10); /* BUG -- this scrolls; it shouldn't */
break;
case 'C': /* cursor right */
m_right(10);
break;
case 'D': /* cursor left */
m_left(10);
break;
case 'E': /* clear home */
m_clear();
break;
case 'H': /* cursor home */
gotoxy(0, 0);
break;
case 'I': /* cursor up, insert line */
m_up(10);
break;
case 'J': /* clear below cursor */
m_cleareos();
break;
case 'K': /* clear remainder of line */
m_cleareol();
break;
case 'L': /* insert a line */
m_addline();
break;
case 'M': /* delete line */
m_deleteline();
break;
case 'Y':
state = escy_putch;
return; /* YES, this should be 'return' */
case 'b': /* set foreground color */
case 'c': /* set background color */
state = ignore;
return;
case 'd': /* clear to cursor position */
get_cursor(&cx, &cy);
clrfrom(0, 0, cx, cy);
break;
case 'e': /* enable cursor */
m_setcursor(CS_BLOCK);
break;
case 'f': /* cursor off */
m_setcursor(CS_INVIS);
break;
case 'j': /* save cursor position */
get_cursor(&savex, &savey);
break;
case 'k': /* restore saved position */
gotoxy(savex, savey);
break;
case 'l': /* clear line */
get_cursor(&cx, &cy);
gotoxy(0, cy);
m_cleareol();
break;
case 'o': /* clear from start of line to cursor */
get_cursor(&cx, &cy);
clrfrom(0, cy, cx, cy);
break;
case 'p': /* reverse video on */
m_standout();
break;
case 'q': /* reverse video off */
m_standend();
break;
case 'v': /* wrap on */
m_clearmode(M_NOWRAP);
break;
case 'w':
m_setmode(M_NOWRAP);
break;
}
state = normal_putch;
}
/*
* escy1_putch(c): for when an ESC Y + char has been seen
*/
int escy1;
void
escy1_putch(c)
int c;
{
gotoxy(c - ' ', escy1 - ' ');
state = normal_putch;
}
/*
* escy_putch(v, c): for when an ESC Y has been seen
*/
void
escy_putch(c)
int c;
{
escy1 = c;
state = escy1_putch;
}
/*
* normal_putch(c): put character 'c' on screen. This is the default
* for when no escape, etc. is active
*/
void
normal_putch(c)
int c;
{
if (c == '\033')
state = putesc;
else
m_putchar(c);
}
static inline
void
put_ch(c)
int c;
{
(*state)(c);
}
int
run(shell, argv)
char *shell, **argv;
{
int fd, oldtty;
long pid;
static char pty[] = "Q:\\VT52@";
/* create our handle */
pid = 0;
do {
pty[7]++; pid++;
fd = Fcreate(pty, FA_SYSTEM|FA_HIDDEN);
} while (fd < 0 && pid < 8);
if (fd < 0) {
printf("couldn't create a pty\n");
quit(2);
}
kidfd = fd;
/* now create the child's handle */
fd = Fopen(pty, 2);
oldtty = Fdup(-1);
if (oldtty < 0) {
Cconws("couldn't dup control terminal!\r\n");
quit(2);
}
Fforce(-1, fd); /* set up new control terminal */
Fforce(0, fd);
Fforce(1, fd);
Fforce(2, fd);
pid = spawnvp(P_NOWAIT, shell, argv); /* spawn child in background */
Fforce(-1, oldtty);
Fforce(0, oldtty);
Fforce(1, oldtty);
Fforce(2, oldtty);
if (pid < 0) {
Cconws("couldn't run ");
Cconws(shell);
Cconws("\r\n");
quit((int)pid);
}
Psetpgrp((int)pid, (int)pid); /* set the child's process group */
Fcntl(fd, &pid, TIOCSPGRP); /* set the terminal process group */
Fclose(fd);
kidpid = pid;
return kidfd;
}
int
quit(x)
int x;
{
m_setnoraw();
if (kidpid)
Pkill((int)-kidpid, SIGHUP);
Pterm(x);
}
#define INBUFSIZ 256
main(argc, argv)
int argc;
char **argv;
{
int fd;
long s, c;
long reads, fdmask;
unsigned char cbuf[INBUFSIZ], *cb;
char *shell, *getenv();
struct sgttyb sg;
if (argc == 3 && !strcmp(argv[1], "-f")) {
fd = Fopen(argv[2], 2);
if (fd < 0) {
perror(argv[2]);
exit(1);
}
s = Pgetpgrp();
Fcntl(fd, &s, TIOCSPGRP);
Fcntl(fd, &sg, TIOCGETP);
sg.sg_flags = RAW;
Fcntl(fd, &sg, TIOCSETP);
}
else {
if (argv[1]) {
argv++;
shell = argv[0];
}
else {
shell = getenv("SHELL");
if (!shell) shell="init.prg";
argv[0] = shell;
argv[1] = 0;
}
fd = run(shell, argv);
}
m_setup(0);
m_size(80, 25);
m_clear();
m_setraw();
m_setmode(M_NOBUCKEY);
state = normal_putch;
fdmask = 1L << fd;
for(;;) {
reads = 1 | fdmask;
Fselect(0, &reads, 0L, 0L);
if (reads & fdmask) {
s = Finstat(fd);
if (s > 0) {
if (s > INBUFSIZ) s = INBUFSIZ;
cb = cbuf;
s = Fread(fd, s, cb);
while (s-- > 0)
put_ch(*cb++);
m_flush();
}
else if (s < 0) {
Cconws("Child exited??\r\n");
quit((int)s);
}
}
if (reads & 1) {
c = Fgetchar(0, 0);
if ( (c & 0xff) == QUITKEY )
quit(0);
Fputchar(fd, c, 0);
}
}
}